package br.com.divulgaqui.persistence.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

/**
 * Implementa todos os métodos CRUDs
 * @author everaldo
 *
 * @param <T>
 */
public abstract class JPAGenericDAO<T> implements GenericDAO<T> {
	
	private Class<T> persistentBean;	
	private EntityManager entityManager;
	
	@SuppressWarnings("unchecked")
	public JPAGenericDAO(EntityManager entityManager) {	
		this.persistentBean = (Class<T>) ((ParameterizedType) 
				getClass().getGenericSuperclass())
				.getActualTypeArguments()[0];
		this.entityManager = entityManager;
	}

	public EntityManager getEntityManager() {
		return entityManager;
	}
	
	@Override
	public T getPorId(Long id){
		return this.entityManager.find(this.persistentBean, id);
	}

	@Override
	public void salvar(T bean) {
		this.entityManager.merge(bean);
		//this.entityManager.flush();
	}
	
	@Override
	public void atualizar(T bean){
		this.entityManager.merge(bean);
	}
	
	public List<T> listar(){
		CriteriaBuilder cri = this.entityManager.getCriteriaBuilder();
		CriteriaQuery<T> query = cri.createQuery(this.persistentBean);
		Root<T> from = query.from(this.persistentBean);
		CriteriaQuery<T> select = query.select(from);			
		TypedQuery<T> tquery = this.entityManager.createQuery(select);			
		return tquery.getResultList();	
	}
}
